package com.jvup.common.inject;

import com.jvup.common.basic.ObjectUtil;
import com.jvup.common.support.base.IViewModel;
import com.qire.antsbinder.utils.TypeUtils;
import com.qire.antsbinder.viewModel.ViewModelFactory;
import com.qire.antsrouter.card.FloorCard;
import com.qire.antsrouter.inject.Injector;
import com.jvup.common.support.base.BaseActivity;
import com.jvup.common.support.base.BaseViewModel;
import com.qire.antsrouter.utils.ClassUtils;

import java.lang.reflect.Field;

import androidx.databinding.ViewDataBinding;

/**
 * 统一ViewModel注入器
 */
public class ViewModelInjector implements Injector<FloorCard, BaseActivity> {

    @Override
    public void inject(Field field, FloorCard postcard, BaseActivity activity) {

        // 如果目标注入对象中存在值，则不做第二次构建注入
        if(ObjectUtil.nonNull(ClassUtils.getFieldValue(field, activity))) {
            return;
        }

        // todo:希望在后期从框架级别解决这个问题
        //-------------------修改页面导航框架页面Go寻址跳转后，页面注入传值会导致自定义注解器执行2次，顾做上面的修复-------------------------

        // 创建ViewModel
        Class<? extends BaseViewModel> viewModelClass = (Class<? extends BaseViewModel>) field.getType();
        Class<?> viewModelProxyClass = null;

        // 检查字段上是否有泛型扩展如果存在则使用字段的泛型扩展作为代理扩展接口
        if(TypeUtils.existGenericType(field)) {
            // 获取在字段上申明的接口类型
            viewModelProxyClass = (Class<?>) TypeUtils.getFieldActualGenericType(field,0);
        } else if(TypeUtils.existGenericType(viewModelClass)) {
            // 获取在类泛型上申明的接口类型
            viewModelProxyClass = (Class<?>) TypeUtils.getSuperclassTypeParameter(viewModelClass, 0);
            viewModelProxyClass = viewModelProxyClass == IViewModel.class ? null : viewModelProxyClass;
        }

        BaseViewModel viewModel = ViewModelFactory.crateByDex(activity, viewModelClass, viewModelProxyClass);

        // 注入创建的ViewModel到目标
        try {
            field.setAccessible(true);
            field.set(activity, viewModel);
            field.setAccessible(false);
        } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }

        // 绑定并获取bindView
        ViewDataBinding bindView = activity.viewDataBinder();

        // 绑定到ViewDataBind的变量ID
        int variableId;
        if((variableId = viewModel.getVariableId()) == BaseViewModel.INVALID_ID) {
            variableId = getVariableId(viewModelProxyClass);
        }
        // 构建ViewModel的代理类
        bindView.setVariable(variableId, viewModel.proxy());
    }

    /**
     * 提取variableId从proxyClass中获取
     * @param proxyClass
     * @return variableId
     */
    private int getVariableId(Class<?> proxyClass) {
        try {
            Field variableIdField = proxyClass.getDeclaredField("variableId");
            return (int) variableIdField.get(proxyClass);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return 0;
    }

}
